/*
 * ChatSDClientView.java
 */
package chatclient;

import com.sd.chat.ChatClientView;
import com.sd.chat.ClientMain;
import com.sd.chat.Logger;
import com.sd.chat.Message;
import com.sd.chat.Post;
import com.sd.chat.ServerData;
import com.sd.chat.UserList;
import com.sd.chat.Utilizador;
import com.sd.chat.WrapLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Rectangle;
import java.util.logging.Level;
import org.jdesktop.application.Action;
import org.jdesktop.application.ResourceMap;
import org.jdesktop.application.SingleFrameApplication;
import org.jdesktop.application.FrameView;
import org.jdesktop.application.TaskMonitor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.EventObject;
import java.util.GregorianCalendar;
import java.util.Vector;
import javax.swing.Timer;
import javax.swing.Icon;
import javax.swing.JDialog;
import javax.swing.JFrame;
import org.jdesktop.application.Application.ExitListener;

/**
 * The application's main frame.
 */
public class ChatSDClientView extends FrameView implements ChatClientView {

    private ClientMain clientLink;
    private Utilizador esteUser;
    private ArrayList<PMPreviewPanel> pmPanels;
    private int selectedPM;
    public Vector<Utilizador> knownUsers;
    private Logger log = new Logger(true);
    private ServerData vdb;

    public ChatSDClientView(SingleFrameApplication app) {
        super(app);
        loadCacheData();
        pmPanels = new ArrayList<PMPreviewPanel>();
        selectedPM = -1;
        initComponents();

        // status bar initialization - message timeout, idle icon and busy animation, etc
        ResourceMap resourceMap = getResourceMap();
        int messageTimeout = resourceMap.getInteger("StatusBar.messageTimeout");
        messageTimer = new Timer(messageTimeout, new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                statusMessageLabel.setText("");
            }
        });
        messageTimer.setRepeats(false);
        int busyAnimationRate = resourceMap.getInteger("StatusBar.busyAnimationRate");
        for (int i = 0; i < busyIcons.length; i++) {
            busyIcons[i] = resourceMap.getIcon("StatusBar.busyIcons[" + i + "]");
        }
        busyIconTimer = new Timer(busyAnimationRate, new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                busyIconIndex = (busyIconIndex + 1) % busyIcons.length;
                statusAnimationLabel.setIcon(busyIcons[busyIconIndex]);
            }
        });
        idleIcon = resourceMap.getIcon("StatusBar.idleIcon");
        statusAnimationLabel.setIcon(idleIcon);
        progressBar.setVisible(false);

        // connecting action tasks to status bar via TaskMonitor
        TaskMonitor taskMonitor = new TaskMonitor(getApplication().getContext());
        taskMonitor.addPropertyChangeListener(new java.beans.PropertyChangeListener() {

            public void propertyChange(java.beans.PropertyChangeEvent evt) {
                String propertyName = evt.getPropertyName();
                if ("started".equals(propertyName)) {
                    if (!busyIconTimer.isRunning()) {
                        statusAnimationLabel.setIcon(busyIcons[0]);
                        busyIconIndex = 0;
                        busyIconTimer.start();
                    }
                    progressBar.setVisible(true);
                    progressBar.setIndeterminate(true);
                } else if ("done".equals(propertyName)) {
                    busyIconTimer.stop();
                    statusAnimationLabel.setIcon(idleIcon);
                    progressBar.setVisible(false);
                    progressBar.setValue(0);
                } else if ("message".equals(propertyName)) {
                    String text = (String) (evt.getNewValue());
                    statusMessageLabel.setText((text == null) ? "" : text);
                    messageTimer.restart();
                } else if ("progress".equals(propertyName)) {
                    int value = (Integer) (evt.getNewValue());
                    progressBar.setVisible(true);
                    progressBar.setIndeterminate(false);
                    progressBar.setValue(value);
                }
            }
        });

        startConfig();
    }

    private void loadCacheData() {
        ObjectInputStream iS;
        boolean loaded = false;
        try {
            iS = new ObjectInputStream(new FileInputStream("clientCache"));
            log.outln("ChatSDClientView Loaded Client Cache from File");

            knownUsers = (Vector<Utilizador>) iS.readObject();

            loaded = true;

        } catch (IOException e) {
            log.erro("ChatSDClientView Loading Client Cache");

        } catch (ClassNotFoundException e) {
        }

        if (!loaded) {
            log.outln("ChatSDClientView Creating New Client Cache");
            knownUsers = new Vector<Utilizador>();
        }
    }

    public void saveCacheData() {
        ObjectOutputStream oS;
        try {
            oS = new ObjectOutputStream(new FileOutputStream("clientCache"));

            oS.writeObject(knownUsers);

        } catch (IOException e) {
            log.erro("ChatSDClientView Saving Client Cache");

        }
    }

    public void startConfig() {
        disableAuth();
        disableTabs();
        setToolBarConnectionOff();
        postsPanel.setLayout(new WrapLayout(FlowLayout.LEFT, 2, 2));
        usersPanel.setLayout(new WrapLayout(FlowLayout.CENTER, 2, 2));
        toolPanel.setLayout(new WrapLayout(FlowLayout.LEFT, 2, 2));
        toolPanelPM.setLayout(new WrapLayout(FlowLayout.LEFT, 2, 2));
        allPMPanel.setLayout(new WrapLayout(FlowLayout.CENTER, 2, 2));
        resetToolPanel();
        allTabs.setSelectedIndex(0);
    }

    public void setSelectedPM(int index) {
        System.out.println("prev selected: " + this.selectedPM);
        System.out.println("now selected: " + index);
        if (this.selectedPM == index) {
            this.selectedPM = -1;
            this.pmPanels.get(index).setSelected(false);
            this.resetPMToolPanel();
            this.pmPanels.get(index).revalidate();
            this.pmPanels.get(index).repaint();
        } else {
            if (this.selectedPM > -1) {
                this.pmPanels.get(this.selectedPM).setSelected(false);
                this.pmPanels.get(this.selectedPM).revalidate();
                this.pmPanels.get(this.selectedPM).repaint();
            }
            this.selectedPM = index;
            this.pmPanels.get(index).setSelected(true);
            this.pmPanels.get(index).revalidate();
            this.pmPanels.get(index).repaint();
            toolPanelPM.removeAll();
            toolPanelPM.add(new composePMPanel(this.vdb.getPms().get((this.vdb.getPms().size()-1)-index), knownUsers));
            toolPanelPM.revalidate();
            toolPanelPM.repaint();
        }
    }

    public void resetToolPanel() {
        toolPanel.removeAll();
        toolPanel.add(new newPostPanel(this));
        toolPanel.revalidate();
        toolPanel.repaint();
    }

    public void setEditPostToolPanel(Post editPost) {
        toolPanel.removeAll();
        toolPanel.add(new editPostPanel(this, editPost));
        toolPanel.revalidate();
        toolPanel.repaint();
    }

    public void setNewCommentToolPanel(int postId) {
        toolPanel.removeAll();
        toolPanel.add(new newCommentPanel(this, postId));
        toolPanel.revalidate();
        toolPanel.repaint();
    }

    public void disableTabs() {
        for (int i = 1; i < allTabs.getTabCount(); i++) {
            allTabs.setEnabledAt(i, false);
        }
        allTabs.revalidate();
        allTabs.repaint();
    }

    public void enableTabs() {
        for (int i = 1; i < allTabs.getTabCount(); i++) {
            allTabs.setEnabledAt(i, true);
        }
        allTabs.revalidate();
        allTabs.repaint();
    }

    public void disableAuth() {
        jLabel5.setEnabled(false);
        jLabel4.setEnabled(false);
        cpassL.setEnabled(false);
        usernameF.setEnabled(false);
        passwordF.setEnabled(false);
        cpassF.setEnabled(false);
        isToRegisterC.setEnabled(false);
        sendAuthB.setEnabled(false);
        tabAuth.revalidate();
        tabAuth.repaint();
        allTabs.setEnabledAt(0, false);
        allTabs.revalidate();
        allTabs.repaint();
    }

    public void enableAuth() {
        jLabel5.setEnabled(true);
        jLabel4.setEnabled(true);
        cpassL.setEnabled(true);
        usernameF.setEnabled(true);
        passwordF.setEnabled(true);
        cpassF.setEnabled(true);
        isToRegisterC.setEnabled(true);
        sendAuthB.setEnabled(true);
        tabAuth.revalidate();
        tabAuth.repaint();
        allTabs.setEnabledAt(0, true);
        allTabs.revalidate();
        allTabs.repaint();
    }

    public void setDisconnected() {
        disableAuth();
        setToolBarConnectionOff();
    }

    public void setConnectionAccepted() {
        enableAuth();
        allTabs.setSelectedIndex(0);
        setToolBarConnectionOn();
    }

    public void setAuthenticated() {
        disableAuth();
        enableTabs();
        allTabs.setSelectedIndex(1);
        resetPMToolPanel();
    }

    public void setToolBarConnectionOn() {
        jLabel1.setEnabled(false);
        serveripF.setEnabled(false);
        connectB.setEnabled(false);
        cleanallB.setEnabled(true);
        jToolBar1.revalidate();
        jToolBar1.repaint();
    }

    public void setToolBarConnectionOff() {
        jLabel1.setEnabled(true);
        serveripF.setEnabled(true);
        connectB.setEnabled(true);
        cleanallB.setEnabled(false);
        jToolBar1.revalidate();
        jToolBar1.repaint();
    }

    public void displayMsg(String msg, int color) {
        constatusT.setText(msg);
        if (color == 0) {
            constatusT.setForeground(Color.black);
        } else if (color == 1) {
            constatusT.setForeground(new Color(33, 153, 36));
        } else if (color == 2) {
            constatusT.setForeground(new Color(183, 185, 25));
        } else {
            constatusT.setForeground(new Color(198, 23, 23));
        }
        constatusT.revalidate();
        constatusT.repaint();
        jToolBar1.revalidate();
        jToolBar1.repaint();
    }

    public ClientMain getClientLink() {
        return clientLink;
    }

    public void setClientLink(ClientMain clientLink) {
        this.clientLink = clientLink;
        final ClientMain cLink = clientLink;
        this.getApplication().addExitListener(new ExitListener() {

            public boolean canExit(EventObject event) {
                System.out.println("starting to exit");
                saveCacheData();
                cLink.setShutdown(true);
                /*try {
                    cLink.join();
                } catch (InterruptedException ex) {
                    System.out.println("erro in join");
                }*/
                return true;
            }

            public void willExit(EventObject event) {
                //serverLink.saveData();
                System.out.println("exiting");
            }
        });
    }

    @Action
    public void disconnectAndClearAll() {
        this.clientLink.getManager().disconnectAndClearAll();
    }

    @Action
    public void tryToConnect() {
        String serverA = serveripF.getText();
        String serverB = backupIpF.getText();
        if (serverA.length() > 1) {
            this.clientLink.getManager().setConnectionInfo(serverA,serverB, rmiCheck.isSelected());
        }
    }

    @Action
    public void tryToAuthenticate() {
        this.setAuthFailMessage("");
        String userN = usernameF.getText();
        boolean fazerRegisto = false;
        if (isToRegisterC.isSelected() && new String(passwordF.getPassword()).equals(new String(cpassF.getPassword()))) {
            fazerRegisto = true;
        } else if (isToRegisterC.isSelected() && !new String(passwordF.getPassword()).equals(new String(cpassF.getPassword()))) {
            this.setAuthFailMessage("As passwords devem coincidir.");
            return;
        }
        this.clientLink.getManager().setAuthInfo(userN, new String(passwordF.getPassword()), fazerRegisto);
    }

    public void newPostSubmit(String texto, boolean hasPic, String picLocation, GregorianCalendar postDate) {
        this.clientLink.getManager().newPost(texto, hasPic, picLocation, postDate);
    }

    public void editSubmit(String texto, int postId) {
        this.clientLink.getManager().editSubmit(texto, postId);
    }

    public void newCommentSubmit(String texto, int postId) {
        this.clientLink.getManager().newCommentSubmit(texto, postId);
    }

    public void eliminateSubmit(int id, boolean post) {
        this.clientLink.getManager().eliminateSubmit(id, post);
    }

    public void newMessageSubmit(Message mess) {
        this.clientLink.getManager().newMessageSubmit(mess);
        this.resetPMToolPanel();
    }

    public void setAuthFailMessage(String msg) {
        authReply.setText(msg);
        authReply.revalidate();
        authReply.repaint();
        tabAuth.revalidate();
        tabAuth.repaint();
    }

    @Action
    public void handleClientInput() {
        //String msg = userInput.getText();
        //userInput.setText("");
        //this.clientLink.getManager().newSimplePost(msg);
    }

    @Action
    public void showAboutBox() {
        if (aboutBox == null) {
            JFrame mainFrame = ChatSDClientApp.getApplication().getMainFrame();
            aboutBox = new ChatSDClientAboutBox(mainFrame);
            aboutBox.setLocationRelativeTo(mainFrame);
        }
        ChatSDClientApp.getApplication().show(aboutBox);
    }

    public Utilizador getEsteUser() {
        return esteUser;
    }

    public void setEsteUser(Utilizador esteUser) {
        this.esteUser = esteUser;
    }

    public void updatePosts(ServerData db) {
        this.vdb = db;
        postsPanel.removeAll();
        for (int i = 0; i < db.getPosts().size(); i++) {
            boolean isMine = (db.getPosts().get(i).getUser().getId() == esteUser.getId());
            Post tempPost = db.getPosts().get(i);
            if (tempPost.isHaspic()) {
                postsPanel.add(new ImagePostPanel(this, tempPost, isMine));
                postsPanel.add(new separatorPanel());

            } else {
                postsPanel.add(new SimplePostPanel(this, tempPost, isMine));
                postsPanel.add(new separatorPanel());
            }
            for (int j = 0; j < db.getComments().size(); j++) {
                if (db.getComments().get(j).getPostId() == tempPost.getId()) {
                    boolean commentIsMine = (db.getComments().get(j).getUser().getId() == esteUser.getId());
                    postsPanel.add(new SimpleCommentPanel(this, db.getComments().get(j), commentIsMine));
                    postsPanel.add(new separatorPanel());
                }
            }
        }
        postsPanel.revalidate();
        postsPanel.repaint();
        /*JScrollBar sb = jScrollPane1.getVerticalScrollBar();
        sb.setValue( sb.getMaximum() );*/
        int height = (int) postsPanel.getPreferredSize().getHeight();
        Rectangle rect = new Rectangle(0, height, 10, 10);
        postsPanel.scrollRectToVisible(rect);



    }

    public void updateUsers(UserList udb) {
        usersPanel.removeAll();
        for (int i = 0; i < udb.userIds.size(); i++) {
            boolean isMe = (udb.userIds.get(i) == esteUser.getId());
            usersPanel.add(new userPanel(udb.userNames.get(i), udb.userIds.get(i), isMe));
            Utilizador tempUser = new Utilizador(udb.userNames.get(i), "", udb.userIds.get(i));
            if (!this.knownUsers.contains(tempUser)) {
                this.knownUsers.add(tempUser);
            }
        }

        usersPanel.revalidate();
        usersPanel.repaint();
    }

    public void updatePMs(ServerData db) {
        this.vdb = db;
        allPMPanel.removeAll();
        pmPanels.clear();
        for (int i = db.getPms().size() - 1; i >= 0; i--) {
            String prevTexto = db.getPms().get(i).getText();
            prevTexto = prevTexto.replaceAll("\n", "");
            prevTexto = prevTexto.replaceAll("\r", "");
            if (prevTexto.length() > 70) {
                prevTexto = prevTexto.substring(0, 65);
            }
            PMPreviewPanel estePanel = new PMPreviewPanel(this, db.getPms().get(i).getId(), db.getPms().get(i).getFrom().getNome(), prevTexto, db.getPms().get(i).getData().getTime().toString(), (db.getPms().size() - 1) - i);
            allPMPanel.add(estePanel);
            pmPanels.add(estePanel);
        }
        this.selectedPM = -1;
        allPMPanel.revalidate();
        allPMPanel.repaint();
    }

    public void resetPMToolPanel() {
        toolPanelPM.removeAll();
        toolPanelPM.add(new composePMPanel(this, knownUsers, esteUser));
        toolPanelPM.revalidate();
        toolPanelPM.repaint();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        mainPanel = new javax.swing.JPanel();
        jToolBar1 = new javax.swing.JToolBar();
        jLabel1 = new javax.swing.JLabel();
        serveripF = new javax.swing.JTextField();
        jLabel3 = new javax.swing.JLabel();
        backupIpF = new javax.swing.JTextField();
        rmiCheck = new javax.swing.JCheckBox();
        connectB = new javax.swing.JButton();
        jSeparator1 = new javax.swing.JToolBar.Separator();
        jLabel2 = new javax.swing.JLabel();
        constatusT = new javax.swing.JLabel();
        jSeparator2 = new javax.swing.JToolBar.Separator();
        cleanallB = new javax.swing.JButton();
        allTabs = new javax.swing.JTabbedPane();
        tabAuth = new javax.swing.JPanel();
        jLabel4 = new javax.swing.JLabel();
        jLabel5 = new javax.swing.JLabel();
        usernameF = new javax.swing.JTextField();
        passwordF = new javax.swing.JPasswordField();
        isToRegisterC = new javax.swing.JCheckBox();
        cpassL = new javax.swing.JLabel();
        cpassF = new javax.swing.JPasswordField();
        sendAuthB = new javax.swing.JButton();
        authReply = new javax.swing.JLabel();
        tabPosts = new javax.swing.JPanel();
        toolPanel = new javax.swing.JPanel();
        jScrollPane1 = new javax.swing.JScrollPane();
        postsPanel = new javax.swing.JPanel();
        jScrollPane2 = new javax.swing.JScrollPane();
        usersPanel = new javax.swing.JPanel();
        jPanel3 = new javax.swing.JPanel();
        toolPanelPM = new javax.swing.JPanel();
        jButton1 = new javax.swing.JButton();
        jButton2 = new javax.swing.JButton();
        jScrollPane3 = new javax.swing.JScrollPane();
        allPMPanel = new javax.swing.JPanel();
        menuBar = new javax.swing.JMenuBar();
        javax.swing.JMenu fileMenu = new javax.swing.JMenu();
        javax.swing.JMenuItem exitMenuItem = new javax.swing.JMenuItem();
        javax.swing.JMenu helpMenu = new javax.swing.JMenu();
        javax.swing.JMenuItem aboutMenuItem = new javax.swing.JMenuItem();
        statusPanel = new javax.swing.JPanel();
        javax.swing.JSeparator statusPanelSeparator = new javax.swing.JSeparator();
        statusMessageLabel = new javax.swing.JLabel();
        statusAnimationLabel = new javax.swing.JLabel();
        progressBar = new javax.swing.JProgressBar();

        mainPanel.setMaximumSize(new java.awt.Dimension(800, 600));
        mainPanel.setMinimumSize(new java.awt.Dimension(800, 600));
        mainPanel.setName("mainPanel"); // NOI18N
        mainPanel.setPreferredSize(new java.awt.Dimension(800, 600));

        jToolBar1.setRollover(true);
        jToolBar1.setName("jToolBar1"); // NOI18N

        org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(chatclient.ChatSDClientApp.class).getContext().getResourceMap(ChatSDClientView.class);
        jLabel1.setText(resourceMap.getString("jLabel1.text")); // NOI18N
        jLabel1.setName("jLabel1"); // NOI18N
        jToolBar1.add(jLabel1);

        serveripF.setText(resourceMap.getString("serveripF.text")); // NOI18N
        serveripF.setMaximumSize(new java.awt.Dimension(80, 20));
        serveripF.setMinimumSize(new java.awt.Dimension(80, 20));
        serveripF.setName("serveripF"); // NOI18N
        serveripF.setPreferredSize(new java.awt.Dimension(80, 20));
        jToolBar1.add(serveripF);

        jLabel3.setText(resourceMap.getString("jLabel3.text")); // NOI18N
        jLabel3.setName("jLabel3"); // NOI18N
        jToolBar1.add(jLabel3);

        backupIpF.setText(resourceMap.getString("backupIpF.text")); // NOI18N
        backupIpF.setMaximumSize(new java.awt.Dimension(80, 20));
        backupIpF.setMinimumSize(new java.awt.Dimension(80, 20));
        backupIpF.setName("backupIpF"); // NOI18N
        backupIpF.setPreferredSize(new java.awt.Dimension(80, 20));
        jToolBar1.add(backupIpF);

        rmiCheck.setText(resourceMap.getString("rmiCheck.text")); // NOI18N
        rmiCheck.setFocusable(false);
        rmiCheck.setHorizontalTextPosition(javax.swing.SwingConstants.RIGHT);
        rmiCheck.setName("rmiCheck"); // NOI18N
        rmiCheck.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        jToolBar1.add(rmiCheck);

        javax.swing.ActionMap actionMap = org.jdesktop.application.Application.getInstance(chatclient.ChatSDClientApp.class).getContext().getActionMap(ChatSDClientView.class, this);
        connectB.setAction(actionMap.get("tryToConnect")); // NOI18N
        connectB.setText(resourceMap.getString("connectB.text")); // NOI18N
        connectB.setFocusable(false);
        connectB.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        connectB.setName("connectB"); // NOI18N
        connectB.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        jToolBar1.add(connectB);

        jSeparator1.setName("jSeparator1"); // NOI18N
        jToolBar1.add(jSeparator1);

        jLabel2.setFont(resourceMap.getFont("jLabel2.font")); // NOI18N
        jLabel2.setText(resourceMap.getString("jLabel2.text")); // NOI18N
        jLabel2.setName("jLabel2"); // NOI18N
        jToolBar1.add(jLabel2);

        constatusT.setText(resourceMap.getString("constatusT.text")); // NOI18N
        constatusT.setName("constatusT"); // NOI18N
        jToolBar1.add(constatusT);

        jSeparator2.setName("jSeparator2"); // NOI18N
        jToolBar1.add(jSeparator2);

        cleanallB.setAction(actionMap.get("disconnectAndClearAll")); // NOI18N
        cleanallB.setText(resourceMap.getString("cleanallB.text")); // NOI18N
        cleanallB.setFocusable(false);
        cleanallB.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        cleanallB.setName("cleanallB"); // NOI18N
        cleanallB.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        jToolBar1.add(cleanallB);

        allTabs.setName("allTabs"); // NOI18N

        tabAuth.setName("tabAuth"); // NOI18N

        jLabel4.setText(resourceMap.getString("jLabel4.text")); // NOI18N
        jLabel4.setName("jLabel4"); // NOI18N

        jLabel5.setText(resourceMap.getString("jLabel5.text")); // NOI18N
        jLabel5.setName("jLabel5"); // NOI18N

        usernameF.setText(resourceMap.getString("usernameF.text")); // NOI18N
        usernameF.setName("usernameF"); // NOI18N

        passwordF.setText(resourceMap.getString("passwordF.text")); // NOI18N
        passwordF.setName("passwordF"); // NOI18N

        isToRegisterC.setText(resourceMap.getString("isToRegisterC.text")); // NOI18N
        isToRegisterC.setName("isToRegisterC"); // NOI18N
        isToRegisterC.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
            public void propertyChange(java.beans.PropertyChangeEvent evt) {
                isToRegisterCPropertyChange(evt);
            }
        });

        cpassL.setText(resourceMap.getString("cpassL.text")); // NOI18N
        cpassL.setName("cpassL"); // NOI18N

        cpassF.setText(resourceMap.getString("cpassF.text")); // NOI18N
        cpassF.setName("cpassF"); // NOI18N

        sendAuthB.setAction(actionMap.get("tryToAuthenticate")); // NOI18N
        sendAuthB.setText(resourceMap.getString("sendAuthB.text")); // NOI18N
        sendAuthB.setName("sendAuthB"); // NOI18N

        authReply.setFont(resourceMap.getFont("authReply.font")); // NOI18N
        authReply.setForeground(resourceMap.getColor("authReply.foreground")); // NOI18N
        authReply.setText(resourceMap.getString("authReply.text")); // NOI18N
        authReply.setName("authReply"); // NOI18N

        javax.swing.GroupLayout tabAuthLayout = new javax.swing.GroupLayout(tabAuth);
        tabAuth.setLayout(tabAuthLayout);
        tabAuthLayout.setHorizontalGroup(
            tabAuthLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(tabAuthLayout.createSequentialGroup()
                .addGap(111, 111, 111)
                .addGroup(tabAuthLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(cpassL)
                    .addComponent(jLabel5)
                    .addComponent(jLabel4))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(tabAuthLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(authReply)
                    .addComponent(sendAuthB)
                    .addComponent(isToRegisterC)
                    .addGroup(tabAuthLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                        .addComponent(passwordF)
                        .addComponent(usernameF, javax.swing.GroupLayout.DEFAULT_SIZE, 143, Short.MAX_VALUE)
                        .addComponent(cpassF)))
                .addContainerGap(583, Short.MAX_VALUE))
        );
        tabAuthLayout.setVerticalGroup(
            tabAuthLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(tabAuthLayout.createSequentialGroup()
                .addGap(67, 67, 67)
                .addGroup(tabAuthLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel4)
                    .addComponent(usernameF, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(18, 18, 18)
                .addGroup(tabAuthLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel5)
                    .addComponent(passwordF, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(18, 18, 18)
                .addGroup(tabAuthLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(cpassL)
                    .addComponent(cpassF, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(18, 18, 18)
                .addComponent(isToRegisterC)
                .addGap(18, 18, 18)
                .addComponent(sendAuthB)
                .addGap(18, 18, 18)
                .addComponent(authReply)
                .addContainerGap(260, Short.MAX_VALUE))
        );

        allTabs.addTab(resourceMap.getString("tabAuth.TabConstraints.tabTitle"), tabAuth); // NOI18N

        tabPosts.setName("tabPosts"); // NOI18N

        toolPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        toolPanel.setMaximumSize(new java.awt.Dimension(488, 106));
        toolPanel.setMinimumSize(new java.awt.Dimension(488, 106));
        toolPanel.setName("toolPanel"); // NOI18N

        javax.swing.GroupLayout toolPanelLayout = new javax.swing.GroupLayout(toolPanel);
        toolPanel.setLayout(toolPanelLayout);
        toolPanelLayout.setHorizontalGroup(
            toolPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 484, Short.MAX_VALUE)
        );
        toolPanelLayout.setVerticalGroup(
            toolPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 102, Short.MAX_VALUE)
        );

        jScrollPane1.setName("jScrollPane1"); // NOI18N

        postsPanel.setBackground(resourceMap.getColor("postsPanel.background")); // NOI18N
        postsPanel.setName("postsPanel"); // NOI18N

        javax.swing.GroupLayout postsPanelLayout = new javax.swing.GroupLayout(postsPanel);
        postsPanel.setLayout(postsPanelLayout);
        postsPanelLayout.setHorizontalGroup(
            postsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 769, Short.MAX_VALUE)
        );
        postsPanelLayout.setVerticalGroup(
            postsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 398, Short.MAX_VALUE)
        );

        jScrollPane1.setViewportView(postsPanel);

        jScrollPane2.setName("jScrollPane2"); // NOI18N

        usersPanel.setBackground(resourceMap.getColor("usersPanel.background")); // NOI18N
        usersPanel.setName("usersPanel"); // NOI18N

        javax.swing.GroupLayout usersPanelLayout = new javax.swing.GroupLayout(usersPanel);
        usersPanel.setLayout(usersPanelLayout);
        usersPanelLayout.setHorizontalGroup(
            usersPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 154, Short.MAX_VALUE)
        );
        usersPanelLayout.setVerticalGroup(
            usersPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 398, Short.MAX_VALUE)
        );

        jScrollPane2.setViewportView(usersPanel);

        javax.swing.GroupLayout tabPostsLayout = new javax.swing.GroupLayout(tabPosts);
        tabPosts.setLayout(tabPostsLayout);
        tabPostsLayout.setHorizontalGroup(
            tabPostsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(tabPostsLayout.createSequentialGroup()
                .addGroup(tabPostsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(tabPostsLayout.createSequentialGroup()
                        .addGap(10, 10, 10)
                        .addComponent(toolPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(tabPostsLayout.createSequentialGroup()
                        .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 771, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 156, Short.MAX_VALUE)))
                .addContainerGap())
        );
        tabPostsLayout.setVerticalGroup(
            tabPostsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(tabPostsLayout.createSequentialGroup()
                .addGroup(tabPostsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                    .addComponent(jScrollPane2, javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 400, Short.MAX_VALUE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(toolPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addContainerGap())
        );

        allTabs.addTab(resourceMap.getString("tabPosts.TabConstraints.tabTitle"), tabPosts); // NOI18N

        jPanel3.setName("jPanel3"); // NOI18N

        toolPanelPM.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        toolPanelPM.setMaximumSize(new java.awt.Dimension(920, 180));
        toolPanelPM.setMinimumSize(new java.awt.Dimension(920, 180));
        toolPanelPM.setName("toolPanelPM"); // NOI18N
        toolPanelPM.setPreferredSize(new java.awt.Dimension(920, 180));

        javax.swing.GroupLayout toolPanelPMLayout = new javax.swing.GroupLayout(toolPanelPM);
        toolPanelPM.setLayout(toolPanelPMLayout);
        toolPanelPMLayout.setHorizontalGroup(
            toolPanelPMLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 919, Short.MAX_VALUE)
        );
        toolPanelPMLayout.setVerticalGroup(
            toolPanelPMLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 203, Short.MAX_VALUE)
        );

        jButton1.setAction(actionMap.get("clickedNovaMensagem")); // NOI18N
        jButton1.setText(resourceMap.getString("jButton1.text")); // NOI18N
        jButton1.setName("jButton1"); // NOI18N
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        jButton2.setAction(actionMap.get("clickedResponderPM")); // NOI18N
        jButton2.setText(resourceMap.getString("jButton2.text")); // NOI18N
        jButton2.setName("jButton2"); // NOI18N

        jScrollPane3.setName("jScrollPane3"); // NOI18N

        allPMPanel.setBackground(resourceMap.getColor("allPMPanel.background")); // NOI18N
        allPMPanel.setMaximumSize(new java.awt.Dimension(921, 243));
        allPMPanel.setMinimumSize(new java.awt.Dimension(921, 243));
        allPMPanel.setName("allPMPanel"); // NOI18N

        javax.swing.GroupLayout allPMPanelLayout = new javax.swing.GroupLayout(allPMPanel);
        allPMPanel.setLayout(allPMPanelLayout);
        allPMPanelLayout.setHorizontalGroup(
            allPMPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 921, Short.MAX_VALUE)
        );
        allPMPanelLayout.setVerticalGroup(
            allPMPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 243, Short.MAX_VALUE)
        );

        jScrollPane3.setViewportView(allPMPanel);

        javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3);
        jPanel3.setLayout(jPanel3Layout);
        jPanel3Layout.setHorizontalGroup(
            jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel3Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(toolPanelPM, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 923, Short.MAX_VALUE)
                    .addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanel3Layout.createSequentialGroup()
                        .addComponent(jButton1)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jButton2))
                    .addComponent(jScrollPane3, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 923, Short.MAX_VALUE))
                .addContainerGap())
        );
        jPanel3Layout.setVerticalGroup(
            jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel3Layout.createSequentialGroup()
                .addComponent(jScrollPane3, javax.swing.GroupLayout.PREFERRED_SIZE, 245, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jButton1)
                    .addComponent(jButton2))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(toolPanelPM, javax.swing.GroupLayout.PREFERRED_SIZE, 207, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(36, Short.MAX_VALUE))
        );

        allTabs.addTab(resourceMap.getString("jPanel3.TabConstraints.tabTitle"), jPanel3); // NOI18N

        javax.swing.GroupLayout mainPanelLayout = new javax.swing.GroupLayout(mainPanel);
        mainPanel.setLayout(mainPanelLayout);
        mainPanelLayout.setHorizontalGroup(
            mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(allTabs, javax.swing.GroupLayout.DEFAULT_SIZE, 948, Short.MAX_VALUE)
            .addComponent(jToolBar1, javax.swing.GroupLayout.DEFAULT_SIZE, 948, Short.MAX_VALUE)
        );
        mainPanelLayout.setVerticalGroup(
            mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(mainPanelLayout.createSequentialGroup()
                .addComponent(jToolBar1, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(allTabs, javax.swing.GroupLayout.DEFAULT_SIZE, 551, Short.MAX_VALUE))
        );

        menuBar.setName("menuBar"); // NOI18N

        fileMenu.setText(resourceMap.getString("fileMenu.text")); // NOI18N
        fileMenu.setName("fileMenu"); // NOI18N

        exitMenuItem.setAction(actionMap.get("quit")); // NOI18N
        exitMenuItem.setName("exitMenuItem"); // NOI18N
        fileMenu.add(exitMenuItem);

        menuBar.add(fileMenu);

        helpMenu.setText(resourceMap.getString("helpMenu.text")); // NOI18N
        helpMenu.setName("helpMenu"); // NOI18N

        aboutMenuItem.setAction(actionMap.get("showAboutBox")); // NOI18N
        aboutMenuItem.setName("aboutMenuItem"); // NOI18N
        helpMenu.add(aboutMenuItem);

        menuBar.add(helpMenu);

        statusPanel.setName("statusPanel"); // NOI18N

        statusPanelSeparator.setName("statusPanelSeparator"); // NOI18N

        statusMessageLabel.setName("statusMessageLabel"); // NOI18N

        statusAnimationLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
        statusAnimationLabel.setName("statusAnimationLabel"); // NOI18N

        progressBar.setName("progressBar"); // NOI18N

        javax.swing.GroupLayout statusPanelLayout = new javax.swing.GroupLayout(statusPanel);
        statusPanel.setLayout(statusPanelLayout);
        statusPanelLayout.setHorizontalGroup(
            statusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(statusPanelSeparator, javax.swing.GroupLayout.DEFAULT_SIZE, 948, Short.MAX_VALUE)
            .addGroup(statusPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(statusMessageLabel)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 778, Short.MAX_VALUE)
                .addComponent(progressBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(statusAnimationLabel)
                .addContainerGap())
        );
        statusPanelLayout.setVerticalGroup(
            statusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(statusPanelLayout.createSequentialGroup()
                .addComponent(statusPanelSeparator, javax.swing.GroupLayout.PREFERRED_SIZE, 2, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addGroup(statusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(statusMessageLabel)
                    .addComponent(statusAnimationLabel)
                    .addComponent(progressBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(3, 3, 3))
        );

        setComponent(mainPanel);
        setMenuBar(menuBar);
        setStatusBar(statusPanel);
    }// </editor-fold>//GEN-END:initComponents

private void isToRegisterCPropertyChange(java.beans.PropertyChangeEvent evt) {//GEN-FIRST:event_isToRegisterCPropertyChange
// TODO add your handling code here:
    if (isToRegisterC.isSelected()) {
        cpassL.setVisible(true);
        cpassF.setVisible(true);
    } else {
        cpassL.setVisible(false);
        cpassF.setVisible(false);
    }
}//GEN-LAST:event_isToRegisterCPropertyChange

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
// TODO add your handling code here:
    resetPMToolPanel();
}//GEN-LAST:event_jButton1ActionPerformed

    @Action
    public void clickedResponderPM() {
        if (this.selectedPM >= 0) {
            toolPanelPM.removeAll();
            for (int h = 0; h < this.knownUsers.size(); h++) {
                log.out("ChatSDClientView known user: " + h + " ->" + this.knownUsers.get(h).toString());
            }
            toolPanelPM.add(new composePMPanel(this, knownUsers, esteUser, this.vdb.getPms().get(this.selectedPM)));
            toolPanelPM.revalidate();
            toolPanelPM.repaint();
        }
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JPanel allPMPanel;
    private javax.swing.JTabbedPane allTabs;
    private javax.swing.JLabel authReply;
    private javax.swing.JTextField backupIpF;
    private javax.swing.JButton cleanallB;
    private javax.swing.JButton connectB;
    private javax.swing.JLabel constatusT;
    private javax.swing.JPasswordField cpassF;
    private javax.swing.JLabel cpassL;
    private javax.swing.JCheckBox isToRegisterC;
    private javax.swing.JButton jButton1;
    private javax.swing.JButton jButton2;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JScrollPane jScrollPane3;
    private javax.swing.JToolBar.Separator jSeparator1;
    private javax.swing.JToolBar.Separator jSeparator2;
    private javax.swing.JToolBar jToolBar1;
    private javax.swing.JPanel mainPanel;
    private javax.swing.JMenuBar menuBar;
    private javax.swing.JPasswordField passwordF;
    private javax.swing.JPanel postsPanel;
    private javax.swing.JProgressBar progressBar;
    private javax.swing.JCheckBox rmiCheck;
    private javax.swing.JButton sendAuthB;
    private javax.swing.JTextField serveripF;
    private javax.swing.JLabel statusAnimationLabel;
    private javax.swing.JLabel statusMessageLabel;
    private javax.swing.JPanel statusPanel;
    private javax.swing.JPanel tabAuth;
    private javax.swing.JPanel tabPosts;
    private javax.swing.JPanel toolPanel;
    private javax.swing.JPanel toolPanelPM;
    private javax.swing.JTextField usernameF;
    private javax.swing.JPanel usersPanel;
    // End of variables declaration//GEN-END:variables
    private final Timer messageTimer;
    private final Timer busyIconTimer;
    private final Icon idleIcon;
    private final Icon[] busyIcons = new Icon[15];
    private int busyIconIndex = 0;
    private JDialog aboutBox;
}
